package RKUjava.util;
import java.util.*;

/** Implements some general array operations. */
public class RKUArrays
{

  /** Clone an array of doubles.
      @return A copy of arr.
  */
  public static final synchronized double[] cloneArray(double[] arr)
    {
      int i;
      double[] res = new double[arr.length];

      for(i=0;i<arr.length;i++) {
	res[i] = arr[i];
      }
      return res;
    }

  /** Clone an array of integers.
      @return A copy of arr.
  */
  public static final synchronized int[] cloneArray(int[] arr)
    {
      int i;
      int[] res = new int[arr.length];

      for(i=0;i<arr.length;i++) {
	res[i] = arr[i];
      }
      return res;
    }

  /** Copy an array of doubles.
      @param src The source array.
      @param dst The destination array.
  */
  public static final void copyArray(double[] src, double[] dst)
    {
      int i;
      for(i=0;i<src.length;i++) {
	dst[i] = src[i];
      }
    }

  /** Copy an array of doubles.
      @param src The source array.
      @param dst The destination array.
      @param srcindex The first index in the source array to start copying from.
  */
  public static final void copyArray(double[] src, double[] dst, int srcindex)
    {
      copyArray(src, dst, srcindex, 0, src.length);
    }

  /** Copy an array of doubles.
      @param src The source array.
      @param dst The destination array.
      @param srcindex The first index in the source array to start copying from.
      @param length The number of entries to copy starting at <tt>srcindex</tt>.
  */
  public static final void copyArray(double[] src, double[] dst, int srcindex, int length)
    {
      copyArray(src, dst, srcindex, 0, length);
    }

  /** Copy an array of doubles.
      @param src The source array.
      @param dst The destination array.
      @param srcindex The first index in the source array to start copying from.
      @param dstindex The first index in the destination array to start copying to.
      @param length The number of entries to copy starting at <tt>srcindex</tt>.
  */
  public static final void copyArray(double[] src, double[] dst, int srcindex, int dstindex, int length)
    {
      int i,j, cnt;
      j = dstindex;
      i = srcindex;
      for(cnt=0;i<length;cnt++) {
	dst[j] = src[i];
	i++;
	j++;
      }
    }

  /** Copy an array of doubles.
      @param src The source array.
      @param dst The destination array.
  */
  public static final void copyArray(int[] src, int[] dst)
    {
      int i;
      for(i=0;i<src.length;i++) {
	dst[i] = src[i];
      }
    }

  /** Copy an array of doubles.
      @param src The source array.
      @param dst The destination array.
      @param srcindex The first index in the source array to start copying from.
  */
  public static final void copyArray(int[] src, int[] dst, int srcindex)
    {
      copyArray(src, dst, srcindex, 0, src.length);
    }

  /** Copy an array of doubles.
      @param src The source array.
      @param dst The destination array.
      @param srcindex The first index in the source array to start copying from.
      @param length The number of entries to copy starting at <tt>srcindex</tt>.
  */
  public static final void copyArray(int[] src, int[] dst, int srcindex, int length)
    {
      copyArray(src, dst, srcindex, 0, length);
    }

  /** Copy an array of doubles.
      @param src The source array.
      @param dst The destination array.
      @param srcindex The first index in the source array to start copying from.
      @param dstindex The first index in the destination array to start copying to.
      @param length The number of entries to copy starting at <tt>srcindex</tt>.
  */
  public static final void copyArray(int[] src, int[] dst, int srcindex, int dstindex, int length)
    {
      int i,j, cnt;
      j = dstindex;
      i = srcindex;
      for(cnt=0;i<length;cnt++) {
	dst[j] = src[i];
	i++;
	j++;
      }
    }

  /** Copy an array of doubles.
      @param src The source array.
      @param dst The destination array.
  */
  public static final void copyArray(Object[] src, Object[] dst)
    {
      int i;
      for(i=0;i<src.length;i++) {
	dst[i] = src[i];
      }
    }

  /** Copy an array of doubles.
      @param src The source array.
      @param dst The destination array.
      @param srcindex The first index in the source array to start copying from.
  */
  public static final void copyArray(Object[] src, Object[] dst, int srcindex)
    {
      copyArray(src, dst, srcindex, 0, src.length);
    }

  /** Copy an array of doubles.
      @param src The source array.
      @param dst The destination array.
      @param srcindex The first index in the source array to start copying from.
      @param length The number of entries to copy starting at <tt>srcindex</tt>.
  */
  public static final void copyArray(Object[] src, Object[] dst, int srcindex, int length)
    {
      copyArray(src, dst, srcindex, 0, length);
    }

  /** Copy an array of doubles.
      @param src The source array.
      @param dst The destination array.
      @param srcindex The first index in the source array to start copying from.
      @param dstindex The first index in the destination array to start copying to.
      @param length The number of entries to copy starting at <tt>srcindex</tt>.
  */
  public static final void copyArray(Object[] src, Object[] dst, int srcindex, int dstindex, int length)
    {
      int i,j, cnt;
      j = dstindex;
      i = srcindex;
      for(cnt=0;i<length;cnt++) {
	dst[j] = src[i];
	i++;
	j++;
      }
    }


  /** Get the maximal object in the array with respect to the ordering given
      by <tt>c</tt>.
      @param arr The array to search.
      @param c The comparator to use as ordering.
      @result The first maximal object with respect to <tt>c</tt>.
  */
  public static final Object getMax(Object[] arr, Comparator c)
    {
      return getMax(arr,0, arr.length, c);
    }

  /** Get the maximal object in the array with respect to the ordering given
      by <tt>c</tt>.
      @param arr The array to search.
      @param fromIndex The index in the array to start the search.
      @param toIndex The first index which is not compared. getMax(arr,0,arr.length, c) will search the whole array.
      @param c The comparator to use as ordering.
      @result The first maximal object with respect to <tt>c</tt>.
  */
  public static final Object getMax(Object[] arr, int fromIndex, int toIndex, Comparator c)
    {
      Object res = null;
      int i;

      if (arr.length>fromIndex)
	res = arr[fromIndex];
      
      for (i=fromIndex;i<toIndex;i++) {
	if (c.compare(res, arr[i])<0)
	  res = arr[i];
      }
      return res;
    }

  /** Get the index of the maximal object in the array with respect to the ordering given
      by <tt>c</tt>.
      @param arr The array to search.
      @param c The comparator to use as ordering.
      @result The first maximal object with respect to <tt>c</tt>.
  */
  public static final int getIndexOfMax(Object[] arr, Comparator c)
    {
      return getIndexOfMax(arr,0, arr.length, c);
    }

  /** Get the index of the maximal object in the array with respect to the ordering given
      by <tt>c</tt>.
      @param arr The array to search.
      @param fromIndex The index in the array to start the search.
      @param toIndex The first index which is not compared. getIndexOfMax(arr,0,arr.length, c) will search the whole array.
      @param c The comparator to use as ordering.
      @result The first maximal object with respect to <tt>c</tt>.
  */
  public static final int getIndexOfMax(Object[] arr, int fromIndex, int toIndex, Comparator c)
    {
      Object best = null;
      int i, besti = 0;

      if (arr.length>fromIndex) {
	best = arr[fromIndex];
	besti = fromIndex;
      };
      
      for (i=fromIndex;i<toIndex;i++) {
	if (c.compare(best, arr[i])<0) {
	  best = arr[i];
	  besti = i;
	}	  
      }
      return besti;
    }

  /** Get the minimal object in the array with respect to the ordering given
      by <tt>c</tt>.
      @param arr The array to search.
      @param c The comparator to use as ordering.
      @result The first minimal object with respect to <tt>c</tt>.
  */
  public static final Object getMin(Object[] arr, Comparator c)
    {
      return getMin(arr,0, arr.length, c);
    }

  /** Get the minimal object in the array with respect to the ordering given
      by <tt>c</tt>.
      @param arr The array to search.
      @param fromIndex The index in the array to start the search.
      @param toIndex The first index which is not compared. getMin(arr,0,arr.length, c) will search the whole array.
      @param c The comparator to use as ordering.
      @result The first minimal object with respect to <tt>c</tt>.
  */
  public static final Object getMin(Object[] arr, int fromIndex, int toIndex, Comparator c)
    {
      Object res = null;
      int i;

      if (arr.length>fromIndex)
	res = arr[fromIndex];
      
      for (i=fromIndex;i<toIndex;i++) {
	if (c.compare(res, arr[i])>0)
	  res = arr[i];
      }
      return res;
    }

  /** Get the index of the minimal object in the array with respect to the ordering given
      by <tt>c</tt>.
      @param arr The array to search.
      @param c The comparator to use as ordering.
      @result The first minimal object with respect to <tt>c</tt>.
  */
  public static final int getIndexOfMin(Object[] arr, Comparator c)
    {
      return getIndexOfMin(arr,0, arr.length, c);
    }

  /** Get the index of the minimal object in the array with respect to the ordering given
      by <tt>c</tt>.
      @param arr The array to search.
      @param fromIndex The index in the array to start the search.
      @param toIndex The first index which is not compared. getIndexOfMin(arr,0,arr.length, c) will search the whole array.
      @param c The comparator to use as ordering.
      @result The first minimal object with respect to <tt>c</tt>.
  */
  public static final int getIndexOfMin(Object[] arr, int fromIndex, int toIndex, Comparator c)
    {
      Object best = null;
      int i, besti = 0;

      if (arr.length>fromIndex) {
	best = arr[fromIndex];
	besti = fromIndex;
      };
      
      for (i=fromIndex;i<toIndex;i++) {
	if (c.compare(best, arr[i])>0) {
	  best = arr[i];
	  besti = i;
	}	  
      }
      return besti;
    }

}
